package cms.web.tag;


import cms.bean.forumCode.ForumCodeReference;
import cms.bean.template.Forum;
import cms.bean.template.TemplateRunObject;
import cms.manage.template.TemplateMain;
import cms.service.template.TemplateService;
import cms.utils.threadLocal.TemplateThreadLocal;
import cms.web.util.JsonUtils;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import static cms.common.SystemConstant.InvokeMethod.INVOKE_OBJECT;
import static cms.common.SystemConstant.LayoutType.PUBLIC_REF_VALUE_PAGE;
import static cms.common.SystemConstant.TemplateTag.INCLUDE;

/**
 * 模板调用对象自定义函数
 * 使用方法
 * ee
 */
@Slf4j
public class TemplateObjectMethods extends BaseTemplateMethods implements TemplateDirectiveModel {
    @Resource
    TemplateService templateService;
    @Resource
    TemplateMain templateMain;

    /**
     * @param env
     * @param params   参数
     * @param loopVars 循环变量
     * @param body     指令内容体
     */
    @Override
    public void doExecute(Environment env, Map params, TemplateModel[] loopVars,
                        TemplateDirectiveBody body) throws TemplateException, IOException {

//        String referenceCode = "";//版块引用代码   ProductRelated_Product_3
//		String run_referenceCode = "";//正在运行的版块引用代码
//		String modulePath = "";//模块路径      templates/bbb/Forum/ProductRelated_Product_Multilayer_Default.html
//        String enc = "UTF-8";
//        boolean parse = true;
        ForumCodeReference forumCodeReference = forumCodeReferenceAction(params, INCLUDE.getLabel());
        if (forumCodeReference == null) {
            throw new TemplateException("自定义引入指令Include，没有包含" + INCLUDE.getLabel() + "标签或引用不存在", env);
        }

        TemplateRunObject templateRunObject = TemplateThreadLocal.get();
        Map<String, Object> runtimeParameter = new HashMap<String, Object>();//运行时参数


        //取得当前正在运行的引入指令
        if (templateRunObject != null && MapUtils.isNotEmpty(templateRunObject.getRuntimeParameter())) {
            runtimeParameter.putAll(templateRunObject.getRuntimeParameter());
        }

        String templatesDir = templateService.findTemplateDirCache();
        if (StringUtils.isNotBlank(forumCodeReference.getReferenceCode())) {
            //模板路径名称(env.getTemplate().getName()方法已过时)
            String templatePathName = env.getCurrentTemplate().getName();

            //模板文件名称  StringUtils.lastIndexOfIgnoreCase从后往前查，不区分大小写
            String name = templatePathName.substring(StringUtils.lastIndexOfIgnoreCase(templatePathName, "/") + 1);//含有后缀
            Forum forum = templateService.findForumCache(templatesDir, forumCodeReference.getReferenceCode());
            if (forum != null) {
                Map<String,Object> parameter = setParameter(params);//提交参数
                String simpleModule = StringUtils.substringBeforeLast(forum.getModule(),"_");//版块模板前缀
                if (name.equals(forum.getLayoutFile()) &&
                        !forum.getLayoutType().equals(PUBLIC_REF_VALUE_PAGE.getValue())
                        && forum.getInvokeMethod().equals(INVOKE_OBJECT.getValue())) {
                    Object obj = templateMain.templateObject(forum,parameter,runtimeParameter);
                    if(log.isInfoEnabled()){
                        log.info("参数={},值={}",simpleModule, JsonUtils.toJson(obj));
                    }
                    env.setVariable(simpleModule, getBeansWrapper().wrap(obj));//引用代码为key  如:Product_Show_1
                    if (body != null) {
                        body.render(env.getOut());
                    }
                }
            }

        }
    }

    /**
     *  取得<@object parameter...></@object>的参数
     * @param params
     * @return
     */
    private Map<String, Object> setParameter(Map params) {
        Map<String,Object> parameter = new HashMap<String,Object>();//提交参数
        if(MapUtils.isNotEmpty(params)) {
            Iterator paramIter = params.entrySet().iterator();
            while (paramIter.hasNext()) {
                Map.Entry ent = (Map.Entry) paramIter.next();
                String key = (ent.getKey() + "").trim();
                if (StringUtils.isNotBlank(key)) {
                    parameter.put(key, (ent.getValue() + "").trim());
                }
            }
        }
        return parameter;
    }
}
